﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MethodWorx.CMS.Content;
using MethodWorx.CMS.UI.Models;
using MethodWorx.CMS.Services;
using MethodWorx.CMS.Administration;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.Web;
using MethodWorx.CMS.UI.Application;
using MethodWorx.CMS.UI.Application.ActionResults;

namespace MethodWorx.CMS.UI.Controllers
{
    public class SchemaController : Controller
    {
        //
        // GET: /Schema/
        private SchemaService schemaService;
        private IPluginRepository plugins;

        public SchemaController(SchemaService schemaService, IPluginRepository plugins)
        {
            if(schemaService == null)
                throw new ArgumentNullException("schemaService");


            this.plugins = plugins;
            this.schemaService = schemaService;
        }

        public ActionResult Index()
        {
            return View(new SchemaModel(this.schemaService));
        }


        public ActionResult NoSelectedItem()
        {
            return View();
        }

        public ActionResult Refresh(bool? keepOpen)
        {
            this.ViewData["keepOpen"] = keepOpen ?? false;
            return View();
        }

        public JsonResult GetToolbarIdeExtensions()
        {
            List<object> result = new List<object>();

            foreach (var p in this.plugins.All().OfType<SafePlugin>().Where(sp => sp.IsSafe && sp.Is<ISchemaDesignPlugin>()))
            {
                foreach(ToolbarIdeExtension tie in p.Invoke<ISchemaDesignPlugin, IEnumerable<ToolbarIdeExtension>>(pl => pl.GetToolbarIdeExtensions()))
                {
                    result.Add(
                        new
                        {
                            text =  tie.Text, 
                            hasText = false, 
                            id =  tie.Id, 
                            icon = tie.Icon,
                            action = "~/GlobalPlugin/" + tie.Id + "/Invoke"
                        });
                }
            }

            return Json(result.ToArray(), JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public ActionResult DeleteContentTemplate(PageTemplate id, Guid constraintId)
        {
            if (id == null)
                throw new WebException("PageTemplate Not Found");

            var constraint = id.ContentTemplateConstraints.FirstOrDefault(c => c.Id == constraintId);

            if (constraint == null)
                throw new WebException("Constraint Not Found");

            var model = new DeleteTemplateModel();
            //
            //  get the other related items
            model.RelatedTo = this.schemaService.GetAllPageTemplatesContaining(constraint.RelatedTemplate).Where(i => i != id);
            model.PageTemplate = id;
            model.Type = "Content Template";

            return View("DeleteTemplate", model);
        }

        [HttpPost]
        public ActionResult DeleteContentTemplate(PageTemplate id, Guid constraintId, string submit)
        {
            if (id == null)
                throw new WebException("PageTemplate Not Found");

            var constraint = id.ContentTemplateConstraints.FirstOrDefault(c => c.Id == constraintId);

            if (constraint == null)
                throw new WebException("Constraint Not Found");

            switch ((submit ?? "").ToLower())
            {
                case "cancel":
                    return new CloseDialogResult();
                    break;
                case "deletetemplate":
                    this.schemaService.DeleteContentTemplate(constraint.RelatedTemplate);
                    return new RefreshSchemaResult().And(new CloseDialogResult());
                    break;
                case "deleterelationship":
                    this.schemaService.DeleteConstraint(id, constraint);
                    return new RefreshSchemaResult().And(new CloseDialogResult());
                    break;
            }

            return null;
        }

        [HttpGet]
        public ActionResult DeletePageTemplate(PageTemplate id, Guid constraintId)
        {
            if (id == null)
                throw new WebException("PageTemplate Not Found");

            var constraint = id.PageTemplateConstraints.FirstOrDefault(c => c.Id == constraintId);

            if (constraint == null)
                throw new WebException("Constraint Not Found");

            var model = new DeleteTemplateModel();
            //
            //  get the other related items
            model.RelatedTo = this.schemaService.GetAllPageTemplatesContaining(constraint.RelatedTemplate).Where(i => i != id);
            model.PageTemplate = id;
            model.Type = "Page Template";

            return View("DeleteTemplate", model);
        }

        [HttpPost]
        public ActionResult DeletePageTemplate(PageTemplate id, Guid constraintId, string submit)
        {
            if (id == null)
                throw new WebException("PageTemplate Not Found");

            var constraint = id.PageTemplateConstraints.FirstOrDefault(c => c.Id == constraintId);

            if (constraint == null)
                throw new WebException("Constraint Not Found");

            switch ((submit ?? "").ToLower())
            {
                case "cancel":
                    return new CloseDialogResult();
                    break;
                case "deletetemplate":
                    this.schemaService.DeletePageTemplate(constraint.RelatedTemplate);
                    return new RefreshSchemaResult().And(new CloseDialogResult());
                    break;
                case "deleterelationship":
                    this.schemaService.DeleteConstraint(id, constraint);
                    return new RefreshSchemaResult().And(new CloseDialogResult());
                    break;
            }

            return null;
        }
    }
}
